package com.sample.dubbo.demo.consumer.config;

import com.sample.dubbo.demo.api.CustomerService;
import org.apache.dubbo.config.*;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import java.util.ArrayList;
import java.util.List;

@Configuration
@Import({ReferenceAnnotationBeanPostProcessor.class})
@ComponentScan(basePackages = "com.sample.dubbo.demo.consumer.task")
public class ConsumerDubboConfiguration {
    @Value("${timeout:1000}")
    private Integer timeout;
    @Value("${query.timeout:1000}")
    private Integer queryTimeout;

    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("dubbo-demo-consumer");
        return applicationConfig;
    }

    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setProtocol("zookeeper");
        // 可以简单配置为：zookeeper://127.0.0.1:2181
        registryConfig.setAddress("127.0.0.1:2181");
        return registryConfig;
    }

    @Bean
    public ConsumerConfig consumerConfig() {
        ConsumerConfig consumerConfig = new ConsumerConfig();
        consumerConfig.setTimeout(timeout);
        consumerConfig.setCheck(false);
        // consumerConfig.setCache("lru");
        consumerConfig.setStub(true);
        consumerConfig.setLoadbalance("roundrobin");
        consumerConfig.setCluster("failfast");
        // 当一个可用的下游服务都没有时，触发Mock处理
        // 如果有一个下游服务，但服务总是抛出异常，不会触发Mock处理
        // 下游服务抛出异常，也相当于服务处于可用状态
        // 如果timeout时，触发Mock处理
        // Mock处理应该是
        consumerConfig.setMock(true);
        // consumerConfig.setMock("com.sample.dubbo.demo.api.CustomerServiceMock");
        // consumerConfig.setMock("force:com.sample.dubbo.demo.api.CustomerServiceMock");
        return consumerConfig;
    }

    @Bean
    public ReferenceConfig<CustomerService> customerServiceReferenceConfig() {
        ReferenceConfig<CustomerService> referenceConfig = new ReferenceConfig<>();
        List<MethodConfig> methodConfigs = new ArrayList<>();
        final MethodConfig query = new MethodConfig();
        query.setName("query");
        query.setTimeout(timeout + queryTimeout);
        methodConfigs.add(query);
        referenceConfig.setMethods(methodConfigs);
        return referenceConfig;
    }

    @Reference
    private CustomerService customerService;

}
